// Copyright (C) 1953-2022 NUDT
// Verilog module name - opensync_1gmac
// Version: V4.1.0.20221206
// Created:
//         by - fenglin 
////////////////////////////////////////////////////////////////////////////
// Description:
//         opensync 1gmac
///////////////////////////////////////////////////////////////////////////
`timescale 1ns/1ps

module opensync_1gmac #(parameter osm_id = 8'h0,local_module_id = 12'd1,opensync_dst_module_id = 12'd0)
(
        i_gmii_clk,
        i_gmii_rst_n,
        i_clk,
        i_rst_n,
		
        iv_command        , 
        i_command_wr      ,
        ov_command_ack    ,
        o_command_ack_wr  ,

        iv_hcp_mid,        
        i_local_cnt_rst,
        i_port_type, 
        
        iv_gmii_rxd  ,
        i_gmii_rx_dv ,
        i_gmii_rx_er ,        
        ov_gmii_txd  ,
        o_gmii_tx_en ,
        o_gmii_tx_er ,
       
        i_tsn_or_tte,     
        
        iv_data,
        i_data_wr,
        o_data_ready,        
            
        ov_data,
        o_data_wr,

        o_osm_req_rx_pulse ,
        o_osm_resp_rx_pulse,
        o_osm_req_tx_pulse ,
        o_osm_resp_tx_pulse
);

// I/O
// clk & rst
input                   i_gmii_clk    ;
input                   i_gmii_rst_n  ;
input                   i_clk         ;                   //125Mhz
input                   i_rst_n       ;
//mbus
input       [63:0]      iv_command       ;
input                   i_command_wr     ;
output      [63:0]      ov_command_ack   ;
output                  o_command_ack_wr ;

input       [11:0]      iv_hcp_mid     ;
input                   i_local_cnt_rst;
input                   i_port_type    ;
input                   i_tsn_or_tte   ;
//input data from gmii
input        [7:0]      iv_gmii_rxd   ;
input                   i_gmii_rx_dv  ;
input                   i_gmii_rx_er  ;
//output data to swc
output       [8:0]      ov_data  ;
output                  o_data_wr;

wire         [23:0]     wv_local_cnt_lct2other;
//input data from swc
input        [8:0]      iv_data     ;
input                   i_data_wr   ;
output                  o_data_ready;
//output data to gmii
output       [7:0]      ov_gmii_txd;
output                  o_gmii_tx_en;
output                  o_gmii_tx_er;

output                  o_osm_req_rx_pulse ;
output                  o_osm_resp_rx_pulse;
output                  o_osm_req_tx_pulse ;
output                  o_osm_resp_tx_pulse;
//rx logic
wire         [7:0]      wv_data_rmp2prx;
wire                    w_data_wr_rmp2prx;

wire         [8:0]      wv_data_prx2ope;
wire                    w_data_wr_prx2ope;
wire         [15:0]     wv_eth_type_prx2ope    ;    
wire         [3:0]      wv_ptp_messagetype_prx2ope   ;   
wire         [23:0]     wv_local_cnt_rx_prx2ope;
wire                    w_diagest_wr_prx2ope   ;

wire         [8:0]      wv_data_ope2cdc;
wire                    w_data_wr_ope2cdc;

wire                    w_slave_port_mpe2oss;
wire                    w_slave_port_oss2prx;
//tx logic
wire         [8:0]      wv_data_cdc2opd;
wire                    w_data_wr_cdc2opd;

wire         [23:0]     wv_local_cnt_rx_opd2ptx;
wire         [15:0]     wv_eth_type_opd2ptx    ;
wire         [7:0]      wv_tsmp_type_opd2ptx   ;
wire         [7:0]      wv_tsmp_subtype_opd2ptx;
wire         [8:0]      wv_data_opd2ptx;
wire                    w_data_wr_opd2ptx;

wire         [8:0]      wv_data_ptx2tmp;
wire                    w_data_wr_ptx2tmp;

wire                    w_osm_req_rx_pulse_prx2oss ;
wire                    w_osm_resp_rx_pulse_prx2oss;
wire                    w_osm_req_tx_pulse_ptx2oss ;
wire                    w_osm_resp_tx_pulse_ptx2oss;
wire                    w_local_cnt_rst_oss2lct    ;

wire         [8:0]      wv_data_cdc2htd  ;
wire                    w_data_wr_cdc2htd;

wire         [8:0]      wv_data_hta2cdc   ;
wire                    w_data_wr_hta2cdc ;
mbus_parse_and_encapsulate_osm mbus_parse_and_encapsulate_osm_inst
(
        .i_clk                        (i_clk  ),
        .i_rst_n                      (i_rst_n),
								 
        .iv_command                   (iv_command          ),
        .i_command_wr                 (i_command_wr        ),
        .ov_command_ack               (ov_command_ack      ),     
        .o_command_ack_wr             (o_command_ack_wr    ),
									 
		.o_slave_port                 (w_slave_port_mpe2oss),
								 
        .iv_rxasyncfifo_overflow_cnt  (16'b0),
        .iv_rxasyncfifo_underflow_cnt (16'b0),
        .iv_txasyncfifo_overflow_cnt  (16'b0),
        .iv_txasyncfifo_underflow_cnt (16'b0)
);

local_count local_count_inst
(
    .i_clk          (i_gmii_clk  ),
    .i_rst_n        (i_gmii_rst_n),
			 
	.i_local_cnt_rst(w_local_cnt_rst_oss2lct),
    .ov_local_cnt   (wv_local_cnt_lct2other)       
);
	
mac_process mac_process_inst
(
        .gmii_rxclk                   (i_gmii_clk          ),
        .gmii_txclk                   (i_gmii_clk          ),
        .rst_n                        (i_gmii_rst_n        ),
                                                           
        .port_type                    (i_port_type         ),
                                                           
        .gmii_rx_dv                   (i_gmii_rx_dv        ),
        .gmii_rx_er                   (i_gmii_rx_er        ),
        .gmii_rxd                     (iv_gmii_rxd         ),

        .gmii_rx_dv_adp2tsnchip       (w_data_wr_rmp2prx   ),
        .gmii_rx_er_adp2tsnchip       (),
        .gmii_rxd_adp2tsnchip         (wv_data_rmp2prx     ),

        .gmii_tx_en_tsnchip2adp       (w_data_wr_ptx2tmp   ),  
        .gmii_tx_er_tsnchip2adp       (1'b0                ),
        .gmii_txd_tsnchip2adp         (wv_data_ptx2tmp[7:0]),
                                                           
        .gmii_tx_en                   (o_gmii_tx_en        ),
        .gmii_tx_er                   (o_gmii_tx_er        ),
        .gmii_txd                     (ov_gmii_txd         )
);
//rx logic
ptp_rx ptp_rx_inst
(
        .i_clk              (i_gmii_clk                ),
        .i_rst_n            (i_gmii_rst_n              ),
                            
        .iv_data            (wv_data_rmp2prx           ),
        .i_data_wr          (w_data_wr_rmp2prx         ),
                            
        .i_slave_port       (w_slave_port_oss2prx      ),

        .iv_local_count     (wv_local_cnt_lct2other    ),		
												          
        .ov_data            (wv_data_prx2ope              ),
        .o_data_wr          (w_data_wr_prx2ope            ),
		.ov_eth_type        (wv_eth_type_prx2ope          ),
		.ov_ptp_messagetype (wv_ptp_messagetype_prx2ope   ),
		.ov_local_count_rx  (wv_local_cnt_rx_prx2ope      ),
        .o_diagest_wr       (w_diagest_wr_prx2ope         ),
		
		.o_osm_req_rx_pulse (w_osm_req_rx_pulse_prx2oss ),
		.o_osm_resp_rx_pulse(w_osm_resp_rx_pulse_prx2oss)
);                           
                             
opensync_protocol_encapsulate #(.osm_id(osm_id),.local_module_id(local_module_id)) opensync_protocol_encapsulate_osm
(
        .i_clk              (i_gmii_clk             ),
        .i_rst_n            (i_gmii_rst_n           ),
        
        .iv_hcp_mid         (iv_hcp_mid             ),
        .iv_opensync_dst_module_id(12'd0             ),
        
        .iv_data            (wv_data_prx2ope        ),
        .i_data_wr          (w_data_wr_prx2ope      ),
		.iv_eth_type        (wv_eth_type_prx2ope    ),
		.iv_ptp_messagetype (wv_ptp_messagetype_prx2ope   ),
        .iv_local_count_rx  (wv_local_cnt_rx_prx2ope      ),
        .i_diagest_wr       (w_diagest_wr_prx2ope         ),
                            
        .ov_data            (wv_data_ope2cdc    ),
        .o_data_wr          (w_data_wr_ope2cdc  )
);

clock_domain_cross #(.frame_gap(5'd8))clock_domain_cross_rx_inst
(
        .i_wr_clk                 (i_gmii_clk       ),
        .i_wr_rst_n               (i_gmii_rst_n     ),
                                                    
        .i_rd_clk                 (i_clk            ),
        .i_rd_rst_n               (i_rst_n          ),
        
        .iv_data                  (wv_data_ope2cdc  ),
        .i_data_wr                (w_data_wr_ope2cdc),
		.o_fifo_ready             (),
        
        .o_fifo_overflow_pulse    (),
        
        .ov_data                  (ov_data   ),//(wv_data_cdc2htd  ),
        .o_data_wr                (o_data_wr ) //(w_data_wr_cdc2htd)
);
/*
head_and_tail_discard head_and_tail_discard_osm
(
.i_clk      (i_clk  ),
.i_rst_n    (i_rst_n),
          
.iv_data    (wv_data_cdc2htd  ),
.i_data_wr  (w_data_wr_cdc2htd),
           
.ov_data    (ov_data   ),
.o_data_wr  (o_data_wr )
);
*/
//tx logic
/*
head_and_tail_add head_and_tail_add_osm
(
.i_clk       (i_clk  ),
.i_rst_n     (i_rst_n),

.i_data_wr   (i_data_wr),
.iv_data     (iv_data  ),

.ov_data     (wv_data_hta2cdc  ),
.o_data_wr   (w_data_wr_hta2cdc)
);
*/
clock_domain_cross #(.frame_gap(5'd22))clock_domain_cross_tx_inst
(
        .i_wr_clk                 (i_clk            ),
        .i_wr_rst_n               (i_rst_n          ),
                                                    
        .i_rd_clk                 (i_gmii_clk       ),
        .i_rd_rst_n               (i_gmii_rst_n     ),
        
        .iv_data                  (iv_data  ),       //(wv_data_hta2cdc  ),
        .i_data_wr                (i_data_wr),       //(w_data_wr_hta2cdc),
        .o_fifo_ready             (o_data_ready     ),
        
        .o_fifo_overflow_pulse    (),
        
        .ov_data                  (wv_data_cdc2opd  ),
        .o_data_wr                (w_data_wr_cdc2opd)
);

opensync_protocol_decapsulate opensync_protocol_decapsulate_inst
(
        .i_clk              (i_gmii_clk              ),
        .i_rst_n            (i_gmii_rst_n            ),
                                                     
        .iv_data            (wv_data_cdc2opd         ),
        .i_data_wr          (w_data_wr_cdc2opd       ),
         
        .ov_local_cnt_rx    (wv_local_cnt_rx_opd2ptx),
        .ov_eth_type        (wv_eth_type_opd2ptx    ), 
        .ov_tsmp_type       (wv_tsmp_type_opd2ptx   ),
        .ov_tsmp_subtype    (wv_tsmp_subtype_opd2ptx),
                            
        .ov_data            (wv_data_opd2ptx      ),
		.o_data_wr          (w_data_wr_opd2ptx    )
    );
ptp_tx ptp_tx_inst
(
        .i_clk                  (i_gmii_clk                 ),
        .i_rst_n                (i_gmii_rst_n               ),
        
        .i_tsn_or_tte 		    (i_tsn_or_tte               ),
       
        .iv_data                (wv_data_opd2ptx            ),
        .i_data_wr              (w_data_wr_opd2ptx          ),
      
        .iv_local_cnt_rx        (wv_local_cnt_rx_opd2ptx    ),
        .iv_eth_type            (wv_eth_type_opd2ptx        ),       
        .iv_tsmp_type           (wv_tsmp_type_opd2ptx       ),      
        .iv_tsmp_subtype        (wv_tsmp_subtype_opd2ptx    ),
		                    
        .iv_local_cnt           (wv_local_cnt_lct2other               ),           
                                
        .ov_data                (wv_data_ptx2tmp            ),
        .o_data_wr              (w_data_wr_ptx2tmp          ),

        .o_osm_req_tx_pulse     (w_osm_req_tx_pulse_ptx2oss ),
        .o_osm_resp_tx_pulse	(w_osm_resp_tx_pulse_ptx2oss)
);

onebit_signal_synchronize local_cnt_rst_synchronize_inst
(
       .i_clk         (i_gmii_clk  ),
       .i_rst_n       (i_gmii_rst_n),
				 
       .i_signal_async(i_local_cnt_rst),
       .o_signal_sync (w_local_cnt_rst_oss2lct)   
);

onebit_signal_synchronize onebit_signal_synchronize_inst
(
    .i_clk                      (i_clk               ),
    .i_rst_n                    (i_rst_n             ),
                                                      
    .i_signal_async             (w_slave_port_mpe2oss),

    .o_signal_sync              (w_slave_port_oss2prx)

); 

onebit_signal_synchronize req_rx_pulse_synchronize_inst
(
       .i_clk         (i_clk  ),
       .i_rst_n       (i_rst_n),
				 
       .i_signal_async(w_osm_req_rx_pulse_prx2oss),
       .o_signal_sync (o_osm_req_rx_pulse)   
);

onebit_signal_synchronize req_tx_pulse_synchronize_inst
(
       .i_clk         (i_clk  ),
       .i_rst_n       (i_rst_n),
				 
       .i_signal_async(w_osm_req_tx_pulse_ptx2oss),
       .o_signal_sync (o_osm_req_tx_pulse)   
);

onebit_signal_synchronize resp_rx_pulse_synchronize_inst
(
       .i_clk         (i_clk  ),
       .i_rst_n       (i_rst_n),
				 
       .i_signal_async(w_osm_resp_rx_pulse_prx2oss),
       .o_signal_sync (o_osm_resp_rx_pulse)   
);

onebit_signal_synchronize resp_tx_pulse_synchronize_inst
(
       .i_clk         (i_clk  ),
       .i_rst_n       (i_rst_n),
				 
       .i_signal_async(w_osm_resp_tx_pulse_ptx2oss),
       .o_signal_sync (o_osm_resp_tx_pulse        )   
);

endmodule 

